﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Storytelling.Entidades;
using System.Collections;

namespace Storytelling.Utils
{
    public sealed class Carga<T> : IEnumerable<string>
         where T : Entidade
    {
        private bool principal;
        private Stack<string> carregamento;

        public Carga()
        {
            principal = true;
            carregamento = new Stack<string>();
        }

        private Carga(Stack<string> carregamento)
        {
            principal = false;
            this.carregamento = carregamento;
        }

        public Carga<TProperty> Carregar<TProperty>(Expression<Func<T, TProperty>> expression)
            where TProperty : Entidade
        {
            return Carregar<TProperty>((MemberExpression) expression.Body);
        }

        public Carga<TProperty> Carregar<TProperty>(Expression<Func<T, ICollection<TProperty>>> expression)
            where TProperty : Entidade
        {
            return Carregar<TProperty>((MemberExpression) expression.Body);
        }

        private Carga<TProperty> Carregar<TProperty>(MemberExpression body)
            where TProperty : Entidade
        {
            if (principal)
            {
                carregamento.Push(body.Member.Name);
            }
            else
            {
                carregamento.Push(string.Format("{0}.{1}", carregamento.Pop(), body.Member.Name));
            }

            return new Carga<TProperty>(this.carregamento);
        }

        public IEnumerator<string> GetEnumerator()
        {
            return carregamento.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return carregamento.GetEnumerator();
        }
    }
}
